package com.mohan;

import com.mohan.aop.impl.ThreadScope;
import com.mohan.bean.Person;
import com.mohan.bean.Student;
import com.mohan.config.*;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.env.Environment;

import java.util.Map;
import java.util.concurrent.TimeUnit;

public class HelloTest {
    @Test
    public void test1() {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        Person person = applicationContext.getBean(Person.class);
        System.out.println("person = " + person);

        final String[] beanNamesForType = applicationContext.getBeanNamesForType(Person.class);
        for (String name : beanNamesForType) {
            System.out.println("name = " + name);
        }
    }

    @Test
    public void test2() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("person.xml");
        final String[] definitionNames = applicationContext.getBeanDefinitionNames();
        for (String name : definitionNames) {
            System.out.println("name = " + name);
        }
    }

    @Test
    public void test3() {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig3.class);
        final String[] definitionNames = applicationContext.getBeanDefinitionNames();
        for (String definitionName : definitionNames) {
            System.out.println("definitionName = " + definitionName);
        }

        final Object colorFactoryBean = applicationContext.getBean("colorFactoryBean");
        final Object colorFactoryBean2 = applicationContext.getBean("colorFactoryBean");
        // 获取到class com.mohan.bean.Color
        System.out.println("colorFactoryBean = " + colorFactoryBean.getClass());
        System.out.println(colorFactoryBean == colorFactoryBean2);

        // 获取到FactoryBean对象
        final Object bean = applicationContext.getBean("&colorFactoryBean");
        System.out.println("bean = " + bean.getClass());
    }

    @Test
    public void test4() {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
        Person person = (Person) applicationContext.getBean("person");
        Person person2 = (Person) applicationContext.getBean("person");
        System.out.println("person2 = " + (person2 == person));
    }

    @Test
    public void test5() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig3.class);
        applicationContext.getBeanFactory().registerScope(ThreadScope.THREAD_SCOPE,new ThreadScope());
        for (int i = 0; i < 2; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "\t" + applicationContext.getBean("person"));
                System.out.println(Thread.currentThread().getName() + "\t" + applicationContext.getBean("person"));
                System.out.println(applicationContext.getBean("person") == applicationContext.getBean("person"));
            }).start();
        }
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void test6() {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfDataSource.class);
        System.out.println("IOC容器初始完成");
//        Person person = (Person) applicationContext.getBean("person");
    }

    @Test
    public void test7() {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig3.class);
        System.out.println("容器创建完成");
        final Environment environment = applicationContext.getEnvironment();
        final String property = environment.getProperty("os.name");
        System.out.println("操作系统的名称为 = " + property);

        for (String name2 : applicationContext.getBeanNamesForType(Person.class)) {
            System.out.println("name2 = " + name2);
        }

        final Map<String, Person> beansOfType = applicationContext.getBeansOfType(Person.class);
        System.out.println("beansOfType = " + beansOfType);
    }

    /**
     * 现在，我们就要提出一个新的需求了，比如，如果当前操作系统是Windows操作系统，
     * 那么就向Spring容器中注册名称为bill的Person对象；
     * 如果当前操作系统是Linux操作系统，那么就向Spring容器中注册名称为linus的Person对象。
     * 要想实现这个需求，我们就得要使用@Conditional注解了。
     */
    @Test
    public void test8() {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig3.class);
        final Environment environment = applicationContext.getEnvironment();
        final String property = environment.getProperty("os.name");
        System.out.println("操作系统的名称为 = " + property);
    }

    @Test
    public void test9() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig3.class);
        System.out.println("容器创建完成");
        applicationContext.close();
        System.out.println("关闭");
    }

    @Test
    public void test10() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig4.class);
        System.out.println("容器创建完成");
        applicationContext.close();
    }

    @Test
    public void test11() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifecle.class);
        System.out.println("容器创建完成");
        for (String name : applicationContext.getBeanDefinitionNames()) {
            System.out.println("name = " + name);
        }
        Student student = (Student) applicationContext.getBean("student");
        System.out.println("student = " + student);
        applicationContext.close();
    }

    @Test
    public void tes12() {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfPropertyValues.class);

    }

    @Test
    public void test13() {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfPropertyValues2.class);

    }
}
